package com.innovation.util.config;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class SimpleObjectOutputStream  extends DataOutputStream{
	public SimpleObjectOutputStream(OutputStream in) {
		super(in);
	}

	/**
	 * 类型字段缓存map
	 */
	static Map<Class<?>,List<Field>> fieldListMap = new Hashtable<Class<?>, List<Field>>();
	
	
	/**
	 * 获取类型的字段列表
	 * @param type
	 * @return
	 */
	static synchronized List<Field> getFieldList(Class<?> type){
		List<Field> result = fieldListMap.get(type);
		if(result==null){
			result = new ArrayList<Field>();
			Class<?> clazz = type;
			Set<String> fieldSet = new HashSet<String>();
			
			while(clazz!=Object.class){
				Field [] fields = clazz.getDeclaredFields();
				for(Field field:fields){
					
					int modifiers = field.getModifiers();
					//如果是用static 或者transient声明 则不需要传输
					if((modifiers&Modifier.TRANSIENT)!=0
							||(modifiers&Modifier.STATIC)!=0){
						continue;
					}
					if(field.getAnnotation(Extern.class)==null){
						if(!fieldSet.contains(field.getName())){
							fieldSet.add(field.getName());
							result.add(field);
						}
					}
					
				}
				clazz = clazz.getSuperclass();
			}
			//字段是无需的，所以需要按字段名字排序以对其
			Collections.sort(result, new Comparator<Field>() {
				public int compare(Field o1, Field o2) {
					return o1.getName().compareTo(o2.getName());
				}
			});
			fieldListMap.put(type, result);
		}
		return result;
	}
	
	
	
	public void writeString(String str) throws IOException{
		byte [] data = str.getBytes("utf-8");
		writeShort(data.length);
		write(data);
	}
	/**
	 * 往当前流写入一个简单类型的对象
	 * @param bean
	 * @throws IllegalArgumentException
	 * @throws IOException
	 * @throws IllegalAccessException
	 */
	public void writeBean(Object bean) throws IOException {
		Class<?> type=  bean.getClass();
		List<Field> fields = getFieldList(type);
		try {
			for(Field field:fields){
				field.setAccessible(true);
				Class<?> fieldType = field.getType();
				Object value = field.get(bean);
				if(value == null){
					value = 0;
				}
				if(fieldType==Integer.class){
					writeInt((Integer)value);
				}else if(fieldType==Byte.class){
					writeByte((Byte)value);
				}else if(fieldType==Short.class){
					writeShort((Byte)value);
				}else if(fieldType==Float.class){
					writeFloat((Float)value);
				}else if(fieldType==Long.class){
					writeLong((Long)value);
				}else if(fieldType==Boolean.class){
					writeByte(((Boolean)value)==true?1:0);
				}else if(fieldType==String.class){
					String str = (String) field.get(bean);
					if(str == null){
						str = "";
					}
					writeString(str);
				}else if(fieldType==Date.class){
					if(field.get(bean) != null){
						Date d = (Date)value;
						writeInt((int)(d.getTime()/1000));
						System.out.println(bean.getClass().getSimpleName()+":"+d.getTime());
					}else{
						writeInt(Integer.valueOf(value.toString()));
					}
				}else{
					value = field.get(bean);
					if(value != null){
						writeString(value.getClass().getSimpleName());
						writeBean(value);
					}
//					throw new IOException("不支持的字段类型："+field);
				}
			}
		} catch (Exception e) {
			throw new IOException(e);
		} 
	}
}
